<?php
/**
 * OrderModel
 * @author Loc
 * @version 1.0
 */
require_once 'Zend/Db/Table/Abstract.php';


/**
 * UserModel
 * @author Loc
 * 
 * Zend_Db_Table_Abstract　クラスからインヘリタンスする
 * データベースのテーブルに操作するため
 */
class OrderModel extends Zend_Db_Table_Abstract
{
    /**
     * データベースのテーブルの名前
     */
    protected $_name = 'order';
    
    
    /**
     * addOrder
     * オーだテーブルにレコードを書き込むためメソッド
     * ～新しいレコードの情報を$dataアレイに記入する
     * ～レコードをデータベースに書き込むためinsertメソッドを読み込むする
     * 
     * @param $user_id
     * @param $room_id
     * @param $ordered_time
     * @param $start_time
     * @param $end_time
	 * @param $rent_price
     * @param $status
     */
    public function addOrder($user_id, $room_id, $ordered_time, $start_time, $end_time, $rent_price, $status){
    	$data = array(
    		'user_id' => $user_id,
    		'room_id' => $room_id,
    		'ordered_time' => $ordered_time,
    		'start_time' => $start_time,
    		'end_time' => $end_time,
    		'rent_price' => $rent_price,
			'status' => $status
    	);
    	
    	return $this->insert($data);
    }
    
    /**
     * updateOrder
     * オーだの情報を更新するメソッド
     * ～更新したい情報を$dataアレイに記入する
     * ～更新のためupdateを読み込むする
     * 
     * @param $id
	 * @param $user_id
     * @param $room_id
     * @param $ordered_time
     * @param $start_time
     * @param $end_time
	 * @param $rent_price
     * @param $status
     */
    public function updateOrder($id, $user_id, $room_id, $ordered_time, $start_time, $end_time, $rent_price, $status){
    	$data = array(
    		'user_id' => $user_id,
    		'room_id' => $room_id,
    		'ordered_time' => $ordered_time,
    		'start_time' => $start_time,
    		'end_time' => $end_time,
    		'rent_price' => $rent_price,
			'status' => $status
    	);
    	$check = $this->update($data, "id = $id");
    	
    	return true;
    }
    
    public function updateOrderData($id, $data){
    	$check = $this->update($data, "id = $id");
    	
    	return $check;
    }
    
    /**
     * deleteOrder
     * かくのオーだを削除するメソッド
     * ～レコードを削除しないで状態を変更するだけ　STATUS_DELETED = 0 
     * ～$del_idsは一覧の削除したいユーザのID、','で区別されます、例えば　1,2,3
     * @param $del_ids
     */
    public function deleteOrder($del_ids){
    	if($this->update(array('status' => 0), "id in ($del_ids)") > 0){
    		
    		return true;
    	}else{
    		
    		return false;
    	}
    }
    
    /**
     * データベースの中に一覧のおーだを取り出すメソッド
     * 
     * @param $search_type : 検索タイプ
     * @param $search_key : キーワード
     * @param $page : ページ（データページングのため） (dùng để phân trang dữ liệu)
     * @param $line_per_page : ぺーじのラインの数（タページングのため）số dòng trên trang (dùng để phân trang dữ liệu)
     */
    public function getListOrder($start_time = null, $end_time = null, $status = -1, $page = NULL, $line_per_page = NULL,$room=0){
  
 		$db = Zend_Registry::get('connectDB');
		$select = $db->select()
					->from(array('o'=>'order'),array('id'=>'o.id','start_time' => 'o.start_time', 'end_time' => 'o.end_time', 'user_id'=> "o.user_id", 'room_id'=>"o.room_id", 'status'=> 'o.status', 'ordered_time' => 'o.ordered_time','rent_price'=>'o.rent_price'))
					->joinLeft(array('u'=>'user'),'u.id = o.user_id',array('username'=>'u.username', 'name'=>'u.name', 'phone'=>"u.phone"))
					->joinLeft(array('r'=>'room'),'r.id = o.room_id',array('code'=>'r.code'));

		if($start_time)
			$select->where("o.start_time >= ?", $start_time);
		
		if($end_time)
			$select->where("o.end_time <= ?", $end_time);
		
		if($status > 0)
			$select->where("o.status = ?", $status);
		
		if($room > 0)
			$select->where("o.room_id = ?", $room);
		//order
		$select->order("o.id");
		
    	//do paging
    	if($page && $line_per_page){
    		$select->limitPage($page, $line_per_page);
    	}
    	
    	$list = $db->fetchAll($select);
    	
    	//$list['rent_total'];
    	foreach ($list as &$v){
    		if($v['status'] == STATUS_NORMAL){
    			$v['rent_total'] = self::calculateFeeCrossday($v['rent_price'], substr($v['start_time'],0,11), substr($v['start_time'], 11, 8), substr($v['end_time'],0,11), substr($v['end_time'],11,8)) + ORDER_FEE;
    		}else if($v['status'] == STATUS_CANCELED){
    			$v['rent_total'] = CANCEL_FEE;
    		}else if(($v['status'] == STATUS_PENALTY)){
    			$v['rent_total'] = self::calculateFeeCrossday(PENALTY_MONEY, substr($v['start_time'],0,11), substr($v['start_time'], 11, 8), substr($v['end_time'],0,11), substr($v['end_time'],11,8));
    		}
    		
    		$v['rent_price'] = number_format($v['rent_price']);
			$v['rent_total'] = number_format($v['rent_total']);
    	}
    	
    	return $list;
    }
    
    /**
     * getListOrderCount
     * 指定条件があってレコードの数を計算するメソッド
     * データページングのため
     *  
     * @param $search_type
     * @param $search_key
     */
    public function getListOrderCount($start_time = null, $end_time = null, $status = -1,$room=0){
    	$db = Zend_Registry::get('connectDB');
		$select = $db->select()
					->from(array('o'=>'order'),array('id'=>'o.id','ordered_time'=>'o.ordered_time', 'start_time' => 'o.start_time', 'end_time' => 'o.end_time', 'user_id'=> "o.user_id", 'room_id'=>"o.room_id"))
					->joinLeft(array('r'=>'room'),'r.id = o.room_id',array('code'=>'r.code'));
		
		if($start_time)
			$select->where("o.start_time >= ?", $start_time);
		
		if($end_time)
			$select->where("o.end_time <= ?", $end_time);
		
		if($status > 0)
			$select->where("o.status = ?", $status);
		if($room > 0)
			$select->where("o.room_id = ?", $room);
		$list = $db->fetchAll($select);
		
		return count($list);
    }
    
    /**
     * fetchOrder
     * IDによってオーだを取り出す
     * Lấy thông tin một order theo id
     * 
     * @param unknown_type $id
     */
  	public function fetchOrder($id, $status = -1){
    	$select = $this->select();
    	$select->where("id = ?", $id);
    	if($status > 0)
    		$select->where("status = ?", $status);
  		$row = $this->fetchRow($select);
    	return $row;
    }
    
    /**
     * Add by tuanna
     * 一日一ルームの一覧のオーだを取り出す。
     * Get list order on a room in a date
     * @param $room_id
     * @param $date
     */
    public function getListOrderOnRoom($room_id, $date, $user_id = NULL){
    	$db = Zend_Registry::get('connectDB');
		$select = $db->select()
					->from(array('o'=>'order'),array('id'=>'o.id','start_time' => 'o.start_time', 'end_time' => 'o.end_time', 'user_id'=> "o.user_id", 'room_id'=>"o.room_id"))
					->joinLeft(array('u'=>'user'),'u.id = o.user_id',array('username'=>'u.username'));
		
		$select->where('o.room_id = ?', $room_id);
		$select->where("DATEDIFF(start_time, '$date') = 0 OR (start_time < '$date' and end_time >= '$date')");
		if($user_id)
			$select->where('o.user_id = ?', $user_id);
		
    	$list = $db->fetchAll($select);
    	
    	return $list;
    }
    
    /**
     * オーだの手数料を計算するメソッド
     * Method for calculate order fee
     * @param $price : rent price for 30'
     * @param $start_time (format hh:mm)
     * @param $end_time (format hh:mm)
     */
    public static function calculateFee($price, $start_time, $end_time){
    	//echo $start_time;
    	$start_hour = substr($start_time, 0, 2);
    	$start_minute = substr($start_time, 3, 2);
    	
    	$end_hour = substr($end_time, 0, 2);
    	$end_minute = substr($end_time, 3, 2);
    	
    	$rent_unit = (($end_hour - $start_hour) * 2) + ($end_minute - $start_minute) / 30;
    	$fee = $rent_unit * $price; 
		
    	return $fee;
    }
    
	public static function calculateFeeCrossday($price, $start_date, $start_time, $end_date, $end_time){		
		$diff_days= (strtotime($end_date) - strtotime($start_date)) / (60 * 60 * 24);
		
		//echo $start_time;
    	$start_hour = substr($start_time, 0, 2);
    	$start_minute = substr($start_time, 3, 2);
    	
    	$end_hour = substr($end_time, 0, 2);
    	$end_minute = substr($end_time, 3, 2);
    	
    	$rent_unit =  $diff_days * 48 + (($end_hour - $start_hour) * 2) + ($end_minute - $start_minute) / 30;
    	$fee = $rent_unit * $price; 
		
    	return $fee;
    }
    
    /**
     * getListUserOrder
     * 指定的なユーザの一覧オーだを取るメソッド
     * Function for get list order of a specific user
     */
    public function getListUserOrder($user_id, $start_time = null, $end_time = null, $status = -1, $page = NULL, $line_per_page = 0,$room=0){
 		$db = Zend_Registry::get('connectDB');
		$select = $db->select()
					->from(array('o'=>'order'),array('id'=>'o.id','start_time' => 'o.start_time', 'end_time' => 'o.end_time', 'user_id'=> "o.user_id", 'room_id'=>"o.room_id", 'status'=> 'o.status', 'ordered_time' => 'o.ordered_time','rent_price'=>'o.rent_price'))
					->joinLeft(array('u'=>'user'),'u.id = o.user_id',array('username'=>'u.username'))
					->joinLeft(array('r'=>'room'),'r.id = o.room_id',array('code'=>'r.code'));
		
		$select->where('o.user_id = ?', $user_id);
		
		if($start_time)
			$select->where("o.start_time >= ?", $start_time);
		
		if($end_time)
			$select->where("o.end_time <= ?", $end_time);
		
		if($status > 0)
			$select->where("o.status = ?", $status);
		if($room > 0)
			$select->where("o.room_id = ?", $room);
		//order
		$select->order("o.start_time DESC");
		
    	//do paging
    	if($page && $line_per_page){
    		$select->limitPage($page, $line_per_page);
    	}
    	
    	$list = $db->fetchAll($select);
    	//Zend_Debug::dump($list);
    	foreach ($list as &$v){
    		if($v['status'] == STATUS_NORMAL){
    			$v['rent_total'] = self::calculateFeeCrossday($v['rent_price'], substr($v['start_time'],0,11), substr($v['start_time'], 11, 8), substr($v['end_time'],0,11), substr($v['end_time'],11,8)) + ORDER_FEE;
    		}else if($v['status'] == STATUS_CANCELED){
    			$v['rent_total'] = CANCEL_FEE;
    		}else if(($v['status'] == STATUS_PENALTY)){
    			$v['rent_total'] = self::calculateFeeCrossday(PENALTY_MONEY, substr($v['start_time'],0,11), substr($v['start_time'], 11, 8), substr($v['end_time'],0,11), substr($v['end_time'],11,8));
    		}
    		$v['rent_price'] = number_format($v['rent_price']);
			$v['rent_total'] = number_format($v['rent_total']);
    	}
    	
    	return $list;   	
    }
    
    public function getListUserOrderCount($user_id, $start_time = null, $end_time = null, $status = -1,$room=0){
    	$db = Zend_Registry::get('connectDB');
		$select = $db->select()
					->from(array('o'=>'order'),array('id'=>'o.id','ordered_time'=>'o.ordered_time', 'start_time' => 'o.start_time', 'end_time' => 'o.end_time', 'user_id'=> "o.user_id", 'room_id'=>"o.room_id"))
					->joinLeft(array('u'=>'user'),'u.id = o.user_id',array('username'=>'u.username'))
					->joinLeft(array('r'=>'room'),'r.id = o.room_id',array('code'=>'r.code'));
		
		$select->where('o.user_id = ?', $user_id);
		
		if($start_time)
			$select->where("o.start_time >= ?", $start_time);
		
		if($end_time)
			$select->where("o.end_time <= ?", $end_time);
		
		if($status > 0)
			$select->where("o.status = ?", $status);
		if($room > 0)
			$select->where("o.room_id = ?", $room);
		$list = $db->fetchAll($select);
		
		return count($list);
    }
    
    
   /**
    * cancel
    * オーだをキャンセルするメソッド
    * Function to cancel an order
    * @param unknown_type $order_id
    */
    public function cancel($order_id, $user_type = NORMAL_USER){
 		Zend_Loader::loadClass("PaymentHistoryModel");
    	
    	//TODO check time
 		$order = $this->fetchOrder($order_id);

 		if(!$order)
 			return "not_found";
    	
 		//TODO 予約をキャンセル可能チェック
 		$current_time = date("Y-m-d H:i:s");
 		$start_time = $order->start_time;
		$now = date("Y-m-d H:i:s", time());
		$check_date = strtotime ( '+2 hours' , strtotime($now)) ;
		$check_date = date('Y-m-d H:i:s', $check_date);
		if($check_date > $start_time && $user_type == NORMAL_USER)
 			return "cannot_cancel";
    	
 		//TODO　オーだがキャンセル可能がある場合はオーだの状態を更新する
 		$data = array(
 			'status' => STATUS_CANCELED
 		);
 		$check = $this->update($data, "id = $order_id");
 		
 		//subtract total money & order count & add order fee
 		$order = $this->fetchOrder($order_id);
 		$payment_history_model = new PaymentHistoryModel();
 		$payment_history_model->addMoneyForMonths($order->user_id, $order->start_time, $order->end_time, $order->rent_price, "subtract");
 		$payment_history_model->addOrderCount(substr($order->start_time, 0, 7), $order->user_id, -1);
		$payment_history_model->addFee(date("Y-m"), $order->user_id, CANCEL_FEE);
 		
 		if($check)
 			return "canceled";
 		else
 			return "error_when_canceled";	
    }
    
    public function getOrderDetail($order_id){
 		$db = Zend_Registry::get('connectDB');
		$select = $db->select()
					->from(array('o'=>'order'),array('id'=>'o.id','start_time' => 'o.start_time', 'end_time' => 'o.end_time', 'user_id'=> "o.user_id", 'room_id'=>"o.room_id", 'status'=> 'o.status', 'ordered_time' => 'o.ordered_time','rent_price'=>'o.rent_price', 'status'=>'o.status'))
					->joinLeft(array('u'=>'user'),'u.id = o.user_id',array('username'=>'u.username'))
					->joinLeft(array('r'=>'room'),'r.id = o.room_id',array('code'=>'r.code', 'number_seat' => 'r.number_seat'));
		
		$select->where('o.id = ?', $order_id);
		
		$row = $db->fetchRow($select);
		
		return $row;
    }
    
    public function checkRoomBusy($room_id, $start_time, $end_time){
    	$select = $this->select();
    	$select->where("room_id = ?", $room_id);
    	$select->where("(start_time <= '$start_time' and end_time > '$start_time') or (start_time >= '$start_time' and start_time < '$end_time')");
    	$select->where('status != ?', STATUS_CANCELED);
    	$select->where('status != ?', STATUS_DELETED);
    	
    	$row = $this->fetchRow($select);
    	if($row)
    		return true;
    	else
    		return false;
    }
}